/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package quienesquien;

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class GameServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    public Statement s; //Esto se usa para las peticiones Mysql



    private HashMap<String, User> Tabla; //Guarda la id de sesion y el usuario
    private HashMap<User, User> Retos; //Guarda usuario Retante, usuario Retado
    private HashMap<User, Integer> Retos2; //Guarda Usuario Retante, numero de partida
    private int Npartidas;

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");

        PrintWriter out = response.getWriter();
    if (s==null){
            try {
                s = crearStatement();
            } catch (SQLException ex) {
                Logger.getLogger(GameServlet.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(GameServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
    }
        HttpSession session = request.getSession();
        String Msg = "";

        //Guardamos el usuario en el hash map al volver de una partida
        if(!Tabla.containsKey(session.getId())){
            if(session.getAttribute("user_info")!=null)
                Tabla.put(session.getId(),(User) session.getAttribute("user_info"));
            
        }
        //Borramos el usuario no disponible de la lista de usuarios
        if(request.getParameter("nd")!=null){
            Tabla.remove(SesionOfUser(request.getParameter("nd")));
            //Eliminamos las invitaciones a la batalla
            Retos.remove(session.getAttribute("user_info"));
            Retos2.remove(session.getAttribute("user_info"));
        }
        //Borramos la invitacion
        
        
//Inicio comprobacion Login/Sesion/Seguridad
        String opcion = request.getParameter("opcion");
        if (opcion != null && opcion.equals("5")) {

            String user = request.getParameter("user");
            String password = request.getParameter("password");
            User new_user = new User();
            
            //borramos datos de sesion por si algun usuario se ha saltado algun paso
             session.removeAttribute("Player");
             session.removeAttribute("Npartida");
             
            //Consulta Mysql a usar:
            String consulta = "SELECT id,nombre,nick,uid,apellidos FROM usuarios WHERE nick = '" + request.getParameter("user") + "' AND passwd = MD5( '" + request.getParameter("passwd") + "' )";
            ResultSet res;
            try {
                res = s.executeQuery(consulta);
                if (!res.next()) {
                    //El usuario/password es incorrecto
                    RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/redirect.jsp");
                    dispatcher.forward(request, response);
                    return;
                } else {
                    //Rellenamos el bean de usuario
                    new_user.setid(res.getInt("id"));
                    new_user.setuid(res.getString("uid"));
                    new_user.setsn(res.getString("apellidos"));
                    new_user.setnm(res.getString("nombre"));
                    new_user.setnick(res.getString("nick"));
                    //Agregamos el bean a su sesion
                    session.setAttribute("user_info", new_user);
                }
            } catch (SQLException ex) {
                out.println(ex.getMessage() + "<br>" + ex.getLocalizedMessage() + "<br>" + ex.getSQLState() + "<br>" + ex.getErrorCode());
                Logger.getLogger(LoginServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
            //Guardamos el usuario en el hash map
            Tabla.put(session.getId(), new_user);

        //Tratamos el Logout
        } else if (opcion != null && opcion.equals("logout")) {
            //Lo borramos de la tabla de conectados
            Tabla.remove(session.getId());
            //Borrar la sesion y todos sus parametros
            session.invalidate();
            response.sendRedirect("index.html");
            return;

        //Tratamos la invitacion del usuario
        } else if (opcion != null && opcion.equals("33")) {
            //creacion de la partida
            int id = Integer.parseInt(request.getParameter("id"));
            User retado = getUserFromId(id, Tabla);
            //añadimos al hashmap retos los dos users retados

            Retos.put((User) session.getAttribute("user_info"), retado);

            Npartidas++;//aumentamos el contador de numero de partida

            session.setAttribute("Npartida", Npartidas);
            Retos2.put((User) session.getAttribute("user_info"), Npartidas);


            //Enviamos al P1 a la partida
            String nickP2=(String) request.getParameter("nickP2");
            response.sendRedirect("partida.html?nickP2="+nickP2);

            //Lo borramos de la lista de usuarios disponibles
            Tabla.remove(session.getId());

         //Generamos un Ficheros excel con las estadisticas y lo devolvemos
        } else if (opcion != null && opcion.equals("estadisticas")) {
            response.setContentType("application/vnd.ms-excel");
            String contentDisposition = "attachment" + ";fileName=\"estadisticas.xls\"";
            response.setHeader("Content-Disposition", contentDisposition);
            out.println(ImprimeEstaditicas());
            return;

        } else {
            //El usuario no se esta logeando, ¿estará logeado?
            if (!isLoged(request, response)) {
                //El usuario no esta logeado, se le devuelve a la pagina principal
                RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/redirect.jsp");
                dispatcher.forward(request, response);
                return;
            }
            //Comprobamos si hemos sido retados
            User Retador = QuienMeHaRetado((User) session.getAttribute("user_info"));
            if (Retador != null) {
                Integer Npartida = Retos2.get(Retador);
                Retos2.remove(Retador);//Borramos la info            
                session.setAttribute("Npartida", Npartidas);
                // Msg = "<h3>#"+Npartidas+" Has sido retado por " + Retador.getnick() + " en unos segundos serás redirigido al juego";
                //Enviamos al P2 a la partida
                response.sendRedirect("partida.html");
                //borramos la info del reto
                Retos.remove(Retador);
                //Lo borramos de la lista de usuarios disponibles
                Tabla.remove(session.getId());
                return;
            }
        }

//Fin comprobacion Login/Sesion/Seguridad
//Escritura de la web
        User usuari = (User) session.getAttribute("user_info");
        String BarraMenu = "Menu <a href=\"game.html?opcion=estadisticas\" target=\"_blank\">Estadisticas</a> <a href=\"game.html?opcion=logout\">Logout</a><br>";
        out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">");
        out.println("<html><head><title>Quien es Quien - Menu</title><meta HTTP-EQUIV=\"REFRESH\" content=\"4; url=game.html\">\n<link href=\"../css/basic.css\" rel=\"stylesheet\" type=\"text/css\" /></head><body>");
        //out.println(Msg + "<br>");
        out.println("<div id=\"All\">");
        //Bloque DIV 1
        out.println("<div id=\"header\">");
        out.println("<img src=\"/IMG/quienesquien/logo.png\" alt=\"Logo\">");
        out.println("<h3>" + BarraMenu + "</h3>");
        out.println("</div>");
        
        //Barra de alertas
       String abandono = request.getParameter("abandono");
        if(abandono!=null){
            if(abandono.equals("0")){
                out.println("<div id=\"alertas\">");
                out.println("<h2> Tu contrincate es un cagao!, ha abandonado la partida</h2>");
                out.println("</div>");
            }else{
                out.println("<div id=\"alertas\">");
                out.println("<h2> Eres un cagao!</h2>");
                out.println("</div>");
            }
        }
        
        String nd =request.getParameter("nd");
        if(nd!=null){
                out.println("<div id=\"alertas\">");
                out.println("<h2> El jugador "+nd+" no se encuentra disponible</h2>");
                out.println("</div>");
        }

        out.println("<div id=\"listado\">");
        out.println(UsuariosConectados(usuari));
        // out.println("<br><br>");
        //  out.println( RetosNow());
        out.println("<br><br>");
        out.println("<p>Numero de Partidas en el servlet: " + Npartidas + "</p><br>");
        //Estadisticas
        // out.println(EstadisticasUser(usuari.getid()));
        out.println("</div>");
        out.println("<h5>Quien es Quien - Telecos Edition - Aplicaciones Telematicas 3 - UPF 2009</h5>");

        out.println("</div></body></html>");
    /*RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/main.jsp");
    dispatcher.forward(request, response);*/
    }

    /*
     * Devuelve una tabla con las estadisticas del usuario
     */
    public String EstadisticasUser(int id) {
        String temp = "Estadisticas:<br><table border=\"1\">";
        temp += "<tr><td>Partidas</td><td>Victorias</td><td>Derrotas" +
                "</td></tr>";
        int total = 0;
        int wins = 0;
        /*
         * TODO codigo MySQL de consulta de estadisticas
         */
        String consulta = "SELECT COUNT( * ) AS N FROM historico_games WHERE id_p1 =1 OR id_p2 =1";
        ResultSet res;
        try {
            res = s.executeQuery(consulta);
            res.next();
            total = res.getInt("N");
            consulta = "SELECT COUNT( * ) AS N FROM historico_games WHERE (id_p1 =1 AND ganador=0)OR (id_p2 =1 AND ganador=1)";
            res = s.executeQuery(consulta);
            res.next();
            wins = res.getInt("N");
        } catch (SQLException ex) {


            Logger.getLogger(GameServlet.class.getName()).log(Level.SEVERE, null, ex);
        }



        temp += "<tr><td>" + total + "</td><td>" + wins + "</td><td>" + (total - wins) + "</td></tr>";

        return temp + "</table>";
    }


    /*
     * Devuelve una tabla con los usuarios conectadosString nickP2=(String) request.getAttribute("nickP2");
     *
     * TODO resolver bug
     */

    public String UsuariosConectados(User usuario) {
        User aux;
        String temp = "<table><caption>Usuarios Disponibles:</caption>\n";
        temp += "<thead><tr><th scope=\"col\">Usuarios</th><th scope=\"col\">Retar</th><th scope=\"col\">Otro</th></tr></thead><tbody>\n";
        Iterator it = Tabla.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            aux=(User) e.getValue();
            if(aux==null)break;
            if(usuario==null)break;
            temp += "<tr><th>" + aux.getnick() + "</th><td>";
            if (!aux.getnick().equals(usuario.getnick())) {
                temp += "<a href=\"?opcion=33&id=" + aux.getid() + "&nickP2="+aux.getnick()+"\">Retar</a>";
            }
            temp += "</td><td>" + e.getKey() + "</td></tr>\n";
        }
        return temp + "</tbody></table>\n";
    }

    /*
     * Comprueba si el usuario esta logeado y tiene un sesion
     */
    public boolean isLoged(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();

        User usuari = (User) session.getAttribute("user_info");
        if (Tabla.containsKey(session.getId()) && ((User) Tabla.get(session.getId())) == usuari) {
            return true;
        }
        return false;
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    @Override
    public void init() {
        try {
            try {
                this.s = crearStatement();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //Creamos el HashMap donde guardaremos los usuarios
        Tabla = new HashMap<String, User>();
        Retos = new HashMap<User, User>();
        Retos2 = new HashMap<User, Integer>();
        Npartidas = 0;
    }

    public Statement crearStatement() throws SQLException, ClassNotFoundException {
        //Comprobamos que tenemos el driver de java mysql
        Class.forName("com.mysql.jdbc.Driver");
        // Establecemos la conexion con la base de datos.
        Connection conexion = DriverManager.getConnection("jdbc:mysql://localhost/quien_es_quien", "quien_es_quien", "quien_es_quien");
        // Preparamos la consulta
        return conexion.createStatement();
    }

    //Inserta las peticiones en la base de datos
    public boolean insertaPeticion(Statement s, String consulta) throws Exception {
        s.executeUpdate(consulta);
        return true;
    }

    /*
     * Devuelve un user del hashmap a partir del Id
     */

    public User getUserFromId(int id, HashMap tabla) {
        User usuari = null;
        Iterator it = tabla.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            if (((User) e.getValue()).getid() == id) {
                return ((User) e.getValue());
            }
        }
        return usuari;
    }
    /*
     * Si estas siendo retado, te devulve el usuario retante, sino devuelve null
     */

    public User QuienMeHaRetado(User retado) {

        Iterator it = Retos.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            if (((User) e.getValue()).getid() == retado.getid()) {
                return (User) e.getKey();
            }
        }
        return null;
    }

    //Crea las estadisticas en formato excel
    public String ImprimeEstaditicas() {
        String result = "";
        ResultSet res;
        //Vicorias (El Pro!)
        String consulta = "SELECT U.nick, COUNT(*) AS Victorias FROM historico_games h, usuarios U WHERE (h.id_p1=U.id AND h.ganador=0) OR (h.id_p2=U.id AND h.ganador=1) GROUP by U.id order by Victorias desc LIMIT 10";
        try {
            res = s.executeQuery(consulta);
            result += "Victorias (El Pro!)\t\n";
            result += "Nick\tVictorias\t\n";
            while (res.next()) {
                result += res.getString(1) + "\t" + res.getInt(2) + "\t\n";
            }
        } catch (SQLException ex) {
            Logger.getLogger(GameServlet.class.getName()).log(Level.SEVERE, null, ex);
        }


        result += "\n\n";
        //Premios Gatillo Loco
        consulta = "SELECT p.nick, rondas FROM historico_games h, usuarios p WHERE (h.id_p1=p.id AND h.ganador=0) OR (h.id_p2=p.id AND h.ganador=1) Group By p.id order by rondas LIMIT 10";
        try {
            res = s.executeQuery(consulta);
            result += "Premio Gatillo Loco\t\n";
            result += "Nick\tRondas\t\n";
            while (res.next()) {
                result += res.getString(1) + "\t" + res.getInt(2) + "\t\n";
            }
        } catch (SQLException ex) {
            Logger.getLogger(GameServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
        result += "\n\n";
        //Premios Vicioso
        consulta = "SELECT p.nick, COUNT(*) AS Total FROM historico_games h, usuarios p WHERE (h.id_p1=p.id ) OR (h.id_p2=p.id) group by p.id order by Total desc LIMIT 10";
        try {
            res = s.executeQuery(consulta);
            result += "Premio Vicioso\t\n";
            result += "Nick\tPartidas Totales\t\n";
            while (res.next()) {
                result += res.getString(1) + "\t" + res.getInt(2) + "\t\n";
            }
        } catch (SQLException ex) {
            Logger.getLogger(GameServlet.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    //Devolvemos la sesion de un usuario a partir de un nick
    private Object SesionOfUser(String nick) {
        Iterator it = Tabla.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry e = (Map.Entry) it.next();
            if (((User) e.getValue()).getnick().equals(nick)) {
                return e.getKey();
            }
        }
        return null;
    }
}